#!/usr/bin/python
import optparse
from nested_gen import *

# ------------------------------------------------------------------- #
def write_matrix(mat, outfile, n = '', m = '', temp = '', phi = '', hdr = True, delim = ','):
    """ OVERVIEW: Writes matrix to a file, with a header containing information about
                  site number, species number, temperature and fill.  By default, the
                  matrix is comma-delimited, but the user can choose another delimiter.
    PARAMETERS:
             mat, a site-species presence matrix
             n, the number of sites
             m, the number of species
             temp, the nestedness temperature
             phi, the matrix fill.
    RETURNS: nothing
    """
    f = open(outfile, 'w')

    # HEADER
    # create header line and write to outfile
    if hdr is True:
        header = 'Sites: ' + str(n) + '    Species: ' + str(m) + '    Temperature: ' + str(temp) + '    Fill: ' + str(phi) + '\n'
        f.write(header)

    # MATRIX
    # convert matrix contents to strings and write to file
    for row in mat:  # loop level 1
        row_string = ""
        for item in row[:-1]:  # loop level 2
            row_string = row_string + str(item) + delim
        # end loop level 2

        # append last item to row_string and end line
        row_string = row_string + str(item) + '\n'

        # write line to outfile
        f.write(row_string)
    # end loop level 1

    f.close() # close outfile
# end write_matrix

# ------------------------------------------------------------------- #
def main():
    """ OVERVIEW: Allows user to generate site-species matrix from the command line.
                  The output is automatically written to a file.
    PARAMETERS:
             -n --sites,      the number of sites
             -m --species,    the number of species
             -f --fill,       the matrix fill.
             -t --temp,       the nestedness temperature
             -p --precision,  the desired temperature precision
             -i --iterations, the maximum number of iterations
             -o --output,     the name of the output file
    RETURNS: nothing
    """
    # declare parser and define options
    parser = optparse.OptionParser()
    parser.add_option('-n', '--sites',   help='number of sites',   dest = 'n', action = 'store')
    parser.add_option('-m', '--species', help='number of species', dest = 'm', action = 'store')
    parser.add_option('-f', '--fill',     help='matrix fill (proportion of nonzero cells)', dest = 'phi', action = 'store')
    parser.add_option('-t', '--temp',     help='desired matrix temperature', dest = 'T', action = 'store')
    parser.add_option('-p', '--precision',  help='temperature precision', dest = 'err',      default = 1, action = 'store')
    parser.add_option('-i', '--iterations', help='maximum iterations',    dest = 'max_iter', default = 100, action = 'store')
    parser.add_option('-o', '--output',     help='output file name',      dest = 'outfile',  default = 'matrix.txt', action = 'store')

    # parse options
    (opts, args) = parser.parse_args()

    # check for mandatory options: sites, species, fill, temperature
    not_enough_info = False
    if opts.n is None:
        print "Missing input: Number of sites"
        not_enough_info = True
    if opts.m is None:
        print "Missing input: Number of species"
        not_enough_info = True
    if opts.phi is None:
        print "Missing input: Fill"
        not_enough_info = True
    if opts.T is None:
        print "Missing input: Temperature"
        not_enough_info = True

    if not_enough_info is True:
        # Not enough information to generate matrix; exit
        print "Exiting script...."
        exit(-1)
    else:
        # convert arguments to numeric
        n   = int(opts.n)
        m   = int(opts.m)
        phi = float(opts.phi)
        T   = float(opts.T)
        err = float(opts.err)
        max_iter = float(opts.max_iter)

        # check for invalid values of fill, temperature
        if phi < 0 or phi > 1:
            print 'Fill out of bounds: Fill must be between 0 and 1'
            exit(-1)
        if T < 0 or T > 100:
            print 'Temperature out of bounds: Temperature must be between 0 and 100'
            exit(-1)

        # Call matrix generator
        print "Generating Matrix..."
        mat_info = pert_c(n,m,phi,T,'','',err,max_iter)
        mat  = mat_info[0] # the site-species matrix
        temp = mat_info[1] # the matrix's real temperature

        # Output to file
        print "Writing to File..."
        write_matrix(mat, opts.outfile, n, m, temp, phi)
# end main
if __name__ == "__main__":
    main()
